package com.greenhouse.protocol.handler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.greenhouse.protocol.ChannelService;
import com.greenhouse.protocol.bean.MqttChannel;
import com.greenhouse.protocol.common.exception.NoFindHandlerException;
import com.greenhouse.protocol.internalmessage.MessageCenter;
import com.greenhouse.protocol.mqtt.MqttHander;
import com.greenhouse.protocol.mqtt.MqttHandlerIntf;
import com.greenhouse.protocol.mqtt.ServerMqttHandlerService;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.mqtt.MqttConnectMessage;
import io.netty.handler.codec.mqtt.MqttFixedHeader;
import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttMessageType;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import io.netty.handler.codec.mqtt.MqttSubscribeMessage;
import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage;
import lombok.extern.slf4j.Slf4j;

/**
 * 默认 mqtthandler处理
 *
 * @author lxr
 * @create 2017-11-20 13:58
 **/

@ChannelHandler.Sharable
@Slf4j
@Component
public class DefaultMqttHandler extends MqttHander {

	private final MqttHandlerIntf mqttHandlerApi;

	@Autowired
	ChannelService channelService;

	public DefaultMqttHandler(MqttHandlerIntf mqttHandlerApi) {
		super(mqttHandlerApi);
		this.mqttHandlerApi = mqttHandlerApi;
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		log.info("【DefaultMqttHandler：channelInactive】" + ctx.channel().localAddress().toString() + "关闭成功");
		mqttHandlerApi.close(ctx.channel());
		MessageCenter.offLine(channelService.getOnLineDeviceNum());
	}

	@Override
	public void doMessage(ChannelHandlerContext channelHandlerContext, MqttMessage mqttMessage) {
		Channel channel = channelHandlerContext.channel();
		ServerMqttHandlerService serverMqttHandlerService;
		if (mqttHandlerApi instanceof ServerMqttHandlerService) {
			serverMqttHandlerService = (ServerMqttHandlerService) mqttHandlerApi;
		} else {
			throw new NoFindHandlerException("server handler 不匹配");
		}
		MqttFixedHeader mqttFixedHeader = mqttMessage.fixedHeader();
		if (mqttFixedHeader.messageType().equals(MqttMessageType.CONNECT)) {
			if (!serverMqttHandlerService.login(channel, (MqttConnectMessage) mqttMessage)) {
				channel.close();
			} else {
				MessageCenter.onLine(channelService.getOnLineDeviceNum());
			}
			return;
		}
		MqttChannel mqttChannel = channelService.getMqttChannel(channelService.getDeviceId(channel));
		if (mqttChannel != null && mqttChannel.isLogin()) {
			switch (mqttFixedHeader.messageType()) {
			case PUBLISH:
				serverMqttHandlerService.publish(channel, (MqttPublishMessage) mqttMessage);
				break;
			case SUBSCRIBE:
				serverMqttHandlerService.subscribe(channel, (MqttSubscribeMessage) mqttMessage);
				break;
			case PINGREQ:
				serverMqttHandlerService.pong(channel);
				break;
			case DISCONNECT:
				serverMqttHandlerService.disconnect(channel);
				break;
			case UNSUBSCRIBE:
				serverMqttHandlerService.unsubscribe(channel, (MqttUnsubscribeMessage) mqttMessage);
				break;
			case PUBACK:
				mqttHandlerApi.puback(channel, mqttMessage);
				break;
			case PUBREC:
				mqttHandlerApi.pubrec(channel, mqttMessage);
				break;
			case PUBREL:
				mqttHandlerApi.pubrel(channel, mqttMessage);
				break;
			case PUBCOMP:
				mqttHandlerApi.pubcomp(channel, mqttMessage);
				break;
			default:
				break;
			}
		}
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		log.info("【DefaultMqttHandler：channelActive】" + ctx.channel().remoteAddress().toString() + "链接成功");
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		log.error("exception", cause);
		mqttHandlerApi.close(ctx.channel());
	}
}
